	
	function initData() {
		perm = new Uint8Array([151,160,137,91,90,15,
                                     131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
                                     190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
                                     88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
                                     77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
                                     102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
                                     135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
                                     5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
                                     223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
                                     129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
                                     251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
                                     49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
                                     138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
                                     151,160,137,91,90,15,
                                     131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
                                     190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
                                     88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
                                     77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
                                     102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
                                     135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
                                     5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
                                     223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
                                     129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
                                     251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
                                     49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
                                     138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
                                    ]);
		grad3 = new Int8Array([0,1,1,1,1,-1,1,-1,1,1,-1,-1,
                   1,0,1,1,1,-1,-1,1,1,-1,1,-1,
                   1,1,0,1,-1,0,-1,1,0,-1,-1,1,
                   1,0,-1,-1,0,-1,0,-1,1,0,1,1]);
		grad4 = new Int8Array([0,1,1,1, 0,1,1,-1, 0,1,-1,1, 0,1,-1,-1,
                   0,-1,1,1, 0,-1,1,-1, 0,-1,-1,1, 0,-1,-1,-1,
                   1,0,1,1, 1,0,1,-1, 1,0,-1,1, 1,0,-1,-1,
                   -1,0,1,1, -1,0,1,-1, -1,0,-1,1, -1,0,-1,-1,
                   1,1,0,1, 1,1,0,-1, 1,-1,0,1, 1,-1,0,-1,
                   -1,1,0,1, -1,1,0,-1, -1,-1,0,1, -1,-1,0,-1,
                   1,1,1,0, 1,1,-1,0, 1,-1,1,0, 1,-1,-1,0,
                   -1,1,1,0, -1,1,-1,0, -1,-1,1,0, -1,-1,-1,0]);
	}
	
	function initGL(canvas) {
		try {
			gl = canvas.getContext("experimental-webgl");
			gl.viewportWidth = canvas.width;
			gl.viewportHeight = canvas.height;
		} catch (e) { }
		if (!gl) {
			alert("Could not initialise WebGL, sorry :-(");
		}
    }

	function getShader(gl, id) {
		var shaderScript = document.getElementById(id);
        if (!shaderScript) {
            return null;
        }

        var str = "";
        var k = shaderScript.firstChild;
        while (k) {
            if (k.nodeType == 3) 
            {
                str += k.textContent;
            }
            k = k.nextSibling;
        }

        var shader;
        if (shaderScript.type == "x-shader/x-fragment") {
            shader = gl.createShader(gl.FRAGMENT_SHADER);
        } else if (shaderScript.type == "x-shader/x-vertex") {
            shader = gl.createShader(gl.VERTEX_SHADER);
        } else {
			return null;
        }

        gl.shaderSource(shader, str);
        gl.compileShader(shader);

        if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
            alert(gl.getShaderInfoLog(shader));
            return null;
        }

        return shader;
	}
  
    var waterShaderProgram;
	var cloudShaderProgram;
	var sunShaderProgram;
	var shaderProgram;
	
	
	
	function initShaders() {
  		loadShaders();
		fragmentShader = getShader(gl, "fur-fs");
		vertexShader = getShader(gl, "fur-vs");
		furShader.program = gl.createProgram();
		gl.attachShader(furShader.program, vertexShader);
		gl.attachShader(furShader.program, fragmentShader);
		gl.linkProgram(furShader.program);
	
		if (!gl.getProgramParameter(furShader.program, gl.LINK_STATUS)) {
			alert("Could not initialize shaders");
		}
		gl.useProgram(furShader.program);
	
		furShader.vertexPositionAttribute = gl.getAttribLocation(furShader.program, "a_position");
		gl.enableVertexAttribArray(furShader.vertexPositionAttribute);
		furShader.vertexNormalAttribute = gl.getAttribLocation(furShader.program, "a_normal");
		gl.enableVertexAttribArray(furShader.vertexNormalAttribute);
		furShader.vertexTexCoordAttribute = gl.getAttribLocation(furShader.program, "a_texCoord");
		gl.enableVertexAttribArray(furShader.vertexTexCoordAttribute);
	
		furShader.pMatrixUniform = gl.getUniformLocation(furShader.program, "pMatrix");
		furShader.mvMatrixUniform = gl.getUniformLocation(furShader.program, "mvMatrix");
		furShader.passIndexUniform = gl.getUniformLocation(furShader.program, "pass_index");
		furShader.shellDistanceUniform = gl.getUniformLocation(furShader.program, "shell_distance");
		furShader.dampenUniform = gl.getUniformLocation(furShader.program, "dampen");
		for (var i=0;i<furShader.textureUniforms.length;i++) {
			furShader.textureUniforms[i] = gl.getUniformLocation(furShader.program, "texture"+i);
		}
	
		fragmentShader = getShader(gl, "uv-fs");
		vertexShader = getShader(gl, "uv-vs");
		uvShader.program = gl.createProgram();
			
		gl.attachShader(uvShader.program, vertexShader);
		gl.attachShader(uvShader.program, fragmentShader);
		gl.linkProgram(uvShader.program);
			
		if (!gl.getProgramParameter(uvShader.program, gl.LINK_STATUS)) {
			alert("Could not initialize shaders");
		}
			
		gl.useProgram(uvShader.program);
				
		uvShader.vertexPositionAttribute = gl.getAttribLocation(uvShader.program, "a_position");
		gl.enableVertexAttribArray(uvShader.vertexPositionAttribute);
		uvShader.vertexTexCoordAttribute = gl.getAttribLocation(uvShader.program, "a_texCoord");
		gl.enableVertexAttribArray(uvShader.vertexTexCoordAttribute);
				
		uvShader.pMatrixUniform = gl.getUniformLocation(uvShader.program, "pMatrix");
		uvShader.mvMatrixUniform = gl.getUniformLocation(uvShader.program, "mvMatrix");
				
		for (var i=0;i<uvShader.textureUniforms.length;i++) {
			uvShader.textureUniforms[i] = gl.getUniformLocation(uvShader.program, "texture"+i);
		}
		
		fragmentShader = getShader(gl, "cube-fs");
		vertexShader = getShader(gl, "cube-vs");
		cubeShader.program = gl.createProgram();
		gl.attachShader(cubeShader.program, vertexShader);
		gl.attachShader(cubeShader.program, fragmentShader);
		gl.linkProgram(cubeShader.program);
		if (!gl.getProgramParameter(cubeShader.program, gl.LINK_STATUS)) {
			alert("Could not initialize shaders");
		}
		
		gl.useProgram(cubeShader.program);
		cubeShader.vertexPositionAttribute = gl.getAttribLocation(cubeShader.program, "a_position");
		gl.enableVertexAttribArray(cubeShader.vertexPositionAttribute);
		cubeShader.pMatrixUniform = gl.getUniformLocation(cubeShader.program, "pMatrix");
		cubeShader.mvMatrixUniform = gl.getUniformLocation(cubeShader.program, "mvMatrix");
		cubeShader.textureUniforms[0] = gl.getUniformLocation(cubeShader.program, "texture0");
		
		var fragmentSunShader = getShader(gl, "shader-sun-fs");
		var vertexSunShader = getShader(gl, "shader-sun-vs");

		sunShaderProgram = gl.createProgram();
		gl.attachShader(sunShaderProgram, vertexSunShader);
		gl.attachShader(sunShaderProgram, fragmentSunShader);
		gl.linkProgram(sunShaderProgram);

		if (!gl.getProgramParameter(sunShaderProgram, gl.LINK_STATUS)) {
		  canvas3d.style.display = "none";
		}

		gl.useProgram(sunShaderProgram);

		sunShaderProgram.vertexPositionAttribute = gl.getAttribLocation(sunShaderProgram, "aVertexPosition");
		gl.enableVertexAttribArray(sunShaderProgram.vertexPositionAttribute);

		sunShaderProgram.textureCoordAttribute = gl.getAttribLocation(sunShaderProgram, "aTextureCoord");
		gl.enableVertexAttribArray(sunShaderProgram.textureCoordAttribute);

		sunShaderProgram.pMatrixUniform = gl.getUniformLocation(sunShaderProgram, "uPMatrix");
		sunShaderProgram.mvMatrixUniform = gl.getUniformLocation(sunShaderProgram, "uMVMatrix");

		sunShaderProgram.permSampler = gl.getUniformLocation(sunShaderProgram, "permTexture");
		sunShaderProgram.gradSampler = gl.getUniformLocation(sunShaderProgram, "gradTexture");
		sunShaderProgram.timeUniform = gl.getUniformLocation(sunShaderProgram, "time");
				      
		var fragmentcloudShader = getShader(gl, "shader-cloud-fs");
		var vertexcloudShader = getShader(gl, "shader-cloud-vs");

		cloudShaderProgram = gl.createProgram();
		gl.attachShader(cloudShaderProgram, vertexcloudShader);
		gl.attachShader(cloudShaderProgram, fragmentcloudShader);
		gl.linkProgram(cloudShaderProgram);

		if (!gl.getProgramParameter(cloudShaderProgram, gl.LINK_STATUS)) {
			canvas3d.style.display = "none";
		}

		gl.useProgram(cloudShaderProgram);

		cloudShaderProgram.vertexPositionAttribute = gl.getAttribLocation(cloudShaderProgram, "aVertexPosition");
		gl.enableVertexAttribArray(cloudShaderProgram.vertexPositionAttribute);

		cloudShaderProgram.textureCoordAttribute = gl.getAttribLocation(cloudShaderProgram, "aTextureCoord");
		gl.enableVertexAttribArray(cloudShaderProgram.textureCoordAttribute);

		cloudShaderProgram.pMatrixUniform = gl.getUniformLocation(cloudShaderProgram, "uPMatrix");
		cloudShaderProgram.mvMatrixUniform = gl.getUniformLocation(cloudShaderProgram, "uMVMatrix");

		cloudShaderProgram.permSampler = gl.getUniformLocation(cloudShaderProgram, "permTexture");
		cloudShaderProgram.gradSampler = gl.getUniformLocation(cloudShaderProgram, "gradTexture");
	
		cloudShaderProgram.timeUniform = gl.getUniformLocation(cloudShaderProgram, "time");
		
		var fragmentWaterShader = getShader(gl, "shader-water-fs");
		var vertexWaterShader = getShader(gl, "shader-water-vs");

		waterShaderProgram = gl.createProgram();
		gl.attachShader(waterShaderProgram, vertexWaterShader);
		gl.attachShader(waterShaderProgram, fragmentWaterShader);
		gl.linkProgram(waterShaderProgram);

		if (!gl.getProgramParameter(waterShaderProgram, gl.LINK_STATUS)) {
		  canvas3d.style.display = "none";
		}

		gl.useProgram(waterShaderProgram);

		waterShaderProgram.vertexPositionAttribute = gl.getAttribLocation(waterShaderProgram, "aVertexPosition");
		gl.enableVertexAttribArray(waterShaderProgram.vertexPositionAttribute);
		
		waterShaderProgram.vertexNormalAttribute = gl.getAttribLocation(waterShaderProgram, "aVertexNormal");
		gl.enableVertexAttribArray(waterShaderProgram.vertexNormalAttribute);

		waterShaderProgram.textureCoordAttribute = gl.getAttribLocation(waterShaderProgram, "aTextureCoord");
		gl.enableVertexAttribArray(waterShaderProgram.textureCoordAttribute);

		waterShaderProgram.pMatrixUniform = gl.getUniformLocation(waterShaderProgram, "uPMatrix");
		waterShaderProgram.mvMatrixUniform = gl.getUniformLocation(waterShaderProgram, "uMVMatrix");
		waterShaderProgram.nMatrixUniform = gl.getUniformLocation(waterShaderProgram, "uNMatrix");

		waterShaderProgram.permSampler = gl.getUniformLocation(waterShaderProgram, "permTexture");
		waterShaderProgram.gradSampler = gl.getUniformLocation(waterShaderProgram, "gradTexture");
		waterShaderProgram.materialShininessUniform = gl.getUniformLocation(waterShaderProgram, "uMaterialShininess");
		waterShaderProgram.ambientColorUniform = gl.getUniformLocation(waterShaderProgram, "uAmbientColor");
		waterShaderProgram.pointLightingLocationUniform = gl.getUniformLocation(waterShaderProgram, "uPointLightingLocation");
		waterShaderProgram.pointLightingSpecularColorUniform = gl.getUniformLocation(waterShaderProgram, "uPointLightingSpecularColor");
		waterShaderProgram.pointLightingDiffuseColorUniform = gl.getUniformLocation(waterShaderProgram, "uPointLightingDiffuseColor");

		waterShaderProgram.timeUniform = gl.getUniformLocation(waterShaderProgram, "time");
		waterShaderProgram.cubemapTextureUniform = gl.getUniformLocation(waterShaderProgram, "cubemap");
		waterShaderProgram.noiseTextureUniform = gl.getUniformLocation(waterShaderProgram, "noise");
		waterShaderProgram.camPositionUniform = gl.getUniformLocation(waterShaderProgram, "camPosition");
	}

	

	var permTexture;
	function initPermTexture() {
		var width = 256;
		var components = 4;
		var pixels = new Uint8Array(width * width * components);
		for(var i = 0; i < width; i++) {
			for(var j = 0; j < width; j++) {
				var offset = (i * width + j) * components;
				var value = perm[(j + perm[i]) & 0xff];
				pixels[offset] = grad3[(value & 0x0f) * 3 + 0] * 64 + 64;
				pixels[offset + 1] = grad3[(value & 0x0f) * 3 + 1] * 64 + 64;
				pixels[offset + 2] = grad3[(value & 0x0f) * 3 + 2] * 64 + 64;
				pixels[offset + 3] = value;
			}
		}
		gl.pixelStorei ( gl.UNPACK_ALIGNMENT, 1 );
		permTexture = gl.createTexture();
    
		gl.bindTexture(gl.TEXTURE_2D, permTexture);
		gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, width, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
		gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
		gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
	}

	var gradTexture;
	function initGradTexture() {
		var width = 256;
		var components = 4;
		var pixels = new Uint8Array(width * width * components);
		for(var i = 0; i<width; i++) {
			for(var j = 0; j<width; j++) {
				var offset = (i * width + j) * components;
				var value = perm[(j+perm[i]) & 0xff];
				pixels[offset] = grad4[(value & 0x1f) * 4 + 0] * 64 + 64;   // Gradient x
				pixels[offset+1] = grad4[(value & 0x1f) * 4 + 1] * 64 + 64; // Gradient y
				pixels[offset+2] = grad4[(value & 0x1f) * 4 + 2] * 64 + 64; // Gradient z
				pixels[offset+3] = grad4[(value & 0x1f) * 4 + 3] * 64 + 64; // Gradient w
			}
		}
		gl.pixelStorei ( gl.UNPACK_ALIGNMENT, 1 );
		gradTexture = gl.createTexture();

		gl.bindTexture(gl.TEXTURE_2D, gradTexture);
		gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, width, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
		gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
		gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
	}
	
function initBuffers() {
		var latitudeBands = 30;
        var longitudeBands = 30;
        var radius = 2;

        var vertexPositionData = [];
        var normalData = [];
        var textureCoordData = [];
        for (var latNumber=0; latNumber <= latitudeBands; latNumber++) {
            var theta = latNumber * Math.PI / latitudeBands;
            var sinTheta = Math.sin(theta);
            var cosTheta = Math.cos(theta);

            for (var longNumber=0; longNumber <= longitudeBands; longNumber++) {
                var phi = longNumber * 2 * Math.PI / longitudeBands;
                var sinPhi = Math.sin(phi);
                var cosPhi = Math.cos(phi);

                var x = cosPhi * sinTheta;
                var y = cosTheta;
                var z = sinPhi * sinTheta;
                var u = 1 - (longNumber / longitudeBands);
                var v = 1 - (latNumber / latitudeBands);

                normalData.push(x);
                normalData.push(y);
                normalData.push(z);
                textureCoordData.push(u);
                textureCoordData.push(v);
                vertexPositionData.push(radius * x);
                vertexPositionData.push(radius * y);
                vertexPositionData.push(radius * z);
            }
        }

        var indexData = [];
        for (var latNumber=0; latNumber < latitudeBands; latNumber++) {
            for (var longNumber=0; longNumber < longitudeBands; longNumber++) {
                var first = (latNumber * (longitudeBands + 1)) + longNumber;
                var second = first + longitudeBands + 1;
                indexData.push(first);
                indexData.push(second);
                indexData.push(first + 1);

                indexData.push(second);
                indexData.push(second + 1);
                indexData.push(first + 1);
            }
        }

        sphereVertexTextureCoordBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexTextureCoordBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordData), gl.STATIC_DRAW);
        sphereVertexTextureCoordBuffer.itemSize = 2;
        sphereVertexTextureCoordBuffer.numItems = textureCoordData.length / 2;

        sphereVertexPositionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexPositionBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), gl.STATIC_DRAW);
        sphereVertexPositionBuffer.itemSize = 3;
        sphereVertexPositionBuffer.numItems = vertexPositionData.length / 3;

        sphereVertexIndexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereVertexIndexBuffer);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), gl.STATIC_DRAW);
        sphereVertexIndexBuffer.itemSize = 1;
        sphereVertexIndexBuffer.numItems = indexData.length;
	
		cubeVertexPositionBuffer = gl.createBuffer();
		gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
		vertices = [
			// Front face
			-5.0, -5.0,  5.0,
			5.0, -5.0,  5.0,
			5.0,  5.0,  5.0,
			-5.0,  5.0,  5.0,

			// Back face
			-5.0, -5.0, -5.0,
			-5.0,  5.0, -5.0,
			5.0,  5.0, -5.0,
			5.0, -5.0, -5.0,

			// Top face
			-5.0,  5.0, -5.0,
			-5.0,  5.0,  5.0,
			5.0,  5.0,  5.0,
			5.0,  5.0, -5.0,

			// Bottom face
			-5.0, -5.0, -5.0,
			5.0, -5.0, -5.0,
			5.0, -5.0,  5.0,
			-5.0, -5.0,  5.0,

			// Right face
			5.0, -5.0, -5.0,
			5.0,  5.0, -5.0,
			5.0,  5.0,  5.0,
			5.0, -5.0,  5.0,

			// Left face
			-5.0, -5.0, -5.0,
			-5.0, -5.0,  5.0,
			-5.0,  5.0,  5.0,
			-5.0,  5.0, -5.0,
		];
		gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
		cubeVertexPositionBuffer.itemSize = 3;
		cubeVertexPositionBuffer.numItems = 24;

		cubeVertexTextureCoordBuffer = gl.createBuffer();
		gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer);
		var textureCoords = [
			// Front face
			-5.0, -5.0,  5.0,
			5.0, -5.0,  5.0,
			5.0,  5.0,  5.0,
			-5.0,  5.0,  5.0,

			// Back face
			-5.0, -5.0, -5.0,
			-5.0,  5.0, -5.0,
			5.0,  5.0, -5.0,
			5.0, -5.0, -5.0,

			// Top face
			-5.0,  5.0, -5.0,
			-5.0,  5.0,  5.0,
			5.0,  5.0,  5.0,
			5.0,  5.0, -5.0,

			// Bottom face
			-5.0, -5.0, -5.0,
			5.0, -5.0, -5.0,
			5.0, -5.0,  5.0,
			-5.0, -5.0,  5.0,

			// Right face
			5.0, -5.0, -5.0,
			5.0,  5.0, -5.0,
			5.0,  5.0,  5.0,
			5.0, -5.0,  5.0,

			// Left face
			-1.0, -1.0, -1.0,
			-1.0, -1.0,  1.0,
			-1.0,  1.0,  1.0,
			-1.0,  1.0, -1.0,
		];
		gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW);
		cubeVertexTextureCoordBuffer.itemSize = 3;
		cubeVertexTextureCoordBuffer.numItems = 24;
		
		cubeVertexIndexBuffer = gl.createBuffer();
		gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
		var cubeVertexIndices = [
		0, 1, 2,      0, 2, 3,    // Front face
		4, 5, 6,      4, 6, 7,    // Back face
		8, 9, 10,     8, 10, 11,  // Top face
		12, 13, 14,   12, 14, 15, // Bottom face
		16, 17, 18,   16, 18, 19, // Right face
		20, 21, 22,   20, 22, 23  // Left face
		];
		gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW);
		cubeVertexIndexBuffer.itemSize = 1;
		cubeVertexIndexBuffer.numItems = 36;
		
		waterVertexPositionBuffer = gl.createBuffer();
		gl.bindBuffer(gl.ARRAY_BUFFER, waterVertexPositionBuffer);
		vertices = [
		  -5.0,  0.0,  -5.0,
		   5.0,  0.0,  -5.0,
		   5.0,  0.0,  5.0,
		  -5.0,  0.0,  5.0
		];
		gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
		waterVertexPositionBuffer.itemSize = 3;
		waterVertexPositionBuffer.numItems = 12;

		waterVertexTextureCoordBuffer = gl.createBuffer();
		gl.bindBuffer(gl.ARRAY_BUFFER, waterVertexTextureCoordBuffer);
		var textureCoords = [
		  -5.0, -5.0,  1.0,
		   5.0, -5.0,  1.0,
		   5.0,  5.0,  1.0,
		  -5.0,  5.0,  1.0
		];
		gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW);
		waterVertexTextureCoordBuffer.itemSize = 3;
		waterVertexTextureCoordBuffer.numItems = 12;
		
		waterVertexNormalBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, waterVertexNormalBuffer);
        var vertexNormals = [
             0.0,  1.0,  0.0,
             0.0,  1.0,  0.0,
             0.0,  1.0,  0.0,
             0.0,  1.0,  0.0,
        ];
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexNormals), gl.STATIC_DRAW);
        waterVertexNormalBuffer.itemSize = 3;
        waterVertexNormalBuffer.numItems = 12;

		waterVertexIndexBuffer = gl.createBuffer();
		gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, waterVertexIndexBuffer);
		var waterVertexIndices = [0, 1, 2, 0, 2, 3];
		gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(waterVertexIndices), gl.STATIC_DRAW);
		waterVertexIndexBuffer.itemSize = 1;
		waterVertexIndexBuffer.numItems = 6;
	}
	
	function initTextures() {
		loadCubeTextures();
		loadOtherTextures();
	}
